#include "fbo.h"

namespace sleek
{
    namespace texture
    {
        fbo::fbo(core::device::Device *mom, core::math::vector2di i) : dev(mom)
        {
            size = i;
            enabled = false;

            glGenFramebuffersEXT(1, &framebuffer);
     		glGenRenderbuffersEXT(1, &depthbuffer);
     		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer);
     		glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, size.width, size.height);

     		status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

     		switch(status)
    		{
    			case GL_FRAMEBUFFER_COMPLETE_EXT: break;
                case GL_FRAMEBUFFER_UNSUPPORTED_EXT: printf("GL_FRAMEBUFFER_UNSUPPORTED_EXT!\n"); return; break;
                default: return;
    		}

    		glGenTextures(1, &texture);
    		glBindTexture(GL_TEXTURE_2D, texture);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width, size.height, 0, GL_BGR, GL_UNSIGNED_BYTE, 0);
            glBindTexture(GL_TEXTURE_2D, 0);
        }
        fbo::~fbo()
        {
            glDeleteRenderbuffersEXT(1, &depthbuffer);
            glDeleteFramebuffersEXT(1, &framebuffer);
            glDeleteTextures(1, &texture);
        }
        core::math::vector2di fbo::getSize()
        {
            return size;
        }
        GLuint fbo::glTexture()
        {
            return texture;
        }
        void fbo::enable(bool i)
        {
            enabled = i;
        }
        bool fbo::isEnable()
        {
            return enabled;
        }
        void fbo::start()
        {
            if(!enabled) return;
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
            glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0);
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthbuffer);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        }
        void fbo::bind()
        {
            glBindTexture(GL_TEXTURE_2D, texture);
        }
        void fbo::end()
        {
            if(!enabled) return;
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
        }
    }
}
